/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.miage.pki.tools;

import java.io.File;
import java.io.FileOutputStream;
import java.io.OutputStream;
import java.security.KeyPair;
import java.security.KeyPairGenerator;
import java.security.PrivateKey;
import java.security.PublicKey;
import java.security.Security;
import java.security.interfaces.DSAParams;
import java.security.interfaces.DSAPrivateKey;
import java.security.interfaces.DSAPublicKey;
import java.security.interfaces.RSAPrivateCrtKey;
import java.security.interfaces.RSAPrivateKey;
import java.security.interfaces.RSAPublicKey;
import org.bouncycastle.asn1.ASN1OutputStream;
import org.bouncycastle.asn1.pkcs.RSAPrivateKeyStructure;

import com.miage.pki.service.PKIServiceImpl;

import sun.misc.BASE64Encoder;


/**
 *
 * @author Gaetan
 */
public class KeyTools {

    private KeyPair keyPair;
    
    public KeyTools(String algo){
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
        
        KeyPairGenerator kpg = null;
        keyPair = null;
        try {
            kpg = KeyPairGenerator.getInstance(algo);
            keyPair = kpg.genKeyPair();
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }
    
    public KeyPair getKeyPair() {
        return keyPair;
    }

    public PrivateKey getPrivateKey() {
        return keyPair.getPrivate();
    }

    public PublicKey getPublicKey() {
        return keyPair.getPublic();
    }

    public static String getInfoPublicKey(PublicKey key) {

        StringBuilder str = new StringBuilder("Clé publique de type : ");
        str.append(key.getAlgorithm());

        if (key instanceof RSAPublicKey) {

            //Affichage RSA
            RSAPublicKey keyRSA = (RSAPublicKey) key;
            str.append("\nModule de chiffrement : ");
            str.append(keyRSA.getModulus());

            str.append("\nExposant public : ");
            str.append(keyRSA.getPublicExponent());

        } else if (key instanceof DSAPublicKey) {

            //Affichage DSA
            DSAPublicKey keyDSA = (DSAPublicKey) key;
            str.append("\nValeur de la clé publique : ");
            str.append(keyDSA.getY());

            DSAParams params = keyDSA.getParams();

            str.append("\nValeur de la base : ");
            str.append(params.getG());

            str.append("\nValeur de prime : ");
            str.append(params.getP());

            str.append("\nValeur de subprime : ");
            str.append(params.getQ());
        }

        return str.toString();
    }

    public static String getInfoPrivateKey(PrivateKey key) {

        StringBuilder str = new StringBuilder("Clé privée de type : ");
        str.append(key.getAlgorithm());

        if (key instanceof RSAPrivateKey) {

            //Affichage RSA
            RSAPrivateKey keyRSA = (RSAPrivateKey) key;
            str.append("\nModule de chiffrement : ");
            str.append(keyRSA.getModulus());

            str.append("\nExposant privé : ");
            str.append(keyRSA.getPrivateExponent());

        } else if (key instanceof DSAPrivateKey) {

            //Affichage DSA
            DSAPrivateKey keyDSA = (DSAPrivateKey) key;
            str.append("\nValeur de la clé privée : ");
            str.append(keyDSA.getX());

            DSAParams params = keyDSA.getParams();

            str.append("\nValeur de la base : ");
            str.append(params.getG());

            str.append("\nValeur de prime : ");
            str.append(params.getP());

            str.append("\nValeur de subprime : ");
            str.append(params.getQ());
        }

        return str.toString();
    }
    
    public static boolean saveKeyFile(OutputStream out, PrivateKey pKey, String fileName) {
        try {
            ASN1OutputStream aOS = new ASN1OutputStream(out);
            //out.close();
            aOS.write("-----BEGIN RSA PRIVATE KEY-----\n".getBytes());
            if(pKey instanceof RSAPrivateKey){
                RSAPrivateCrtKey rsaKey = (RSAPrivateCrtKey)pKey;
                RSAPrivateKeyStructure pKeyStruct = new RSAPrivateKeyStructure(rsaKey.getModulus(), rsaKey.getPublicExponent(), rsaKey.getPrivateExponent(), rsaKey.getPrimeP(), rsaKey.getPrimeQ(), rsaKey.getPrimeExponentP(), rsaKey.getPrimeExponentQ(), rsaKey.getCrtCoefficient());
                aOS.write(new BASE64Encoder().encode(pKeyStruct.getDEREncoded()).getBytes());
            }else{
                aOS.write(new BASE64Encoder().encode(((DSAPrivateKey)pKey).getEncoded()).getBytes());
            }
            aOS.write("\n-----END RSA PRIVATE KEY-----\n".getBytes());
            aOS.close();
        } catch (Exception ex) {
            ex.printStackTrace();
            return false;
        }
        return true;
    }

}
